#include <vector>
using namespace std;
#include <wx/wx.h>
#include "EnhancedStatusBar.h"
EnhancedStatusBarItem::EnhancedStatusBarItem(wxWindow *pWidget, int pPos, ESB_HorizontalAlignment pha, ESB_VerticalAlignment pva) : widget(pWidget), pos(pPos), horizontalAlignment(pha), verticalAlignment(pva)
{

}

EnhancedStatusBar::EnhancedStatusBar(wxWindow *parent, wxWindowID id, long style, const  wxString &name) : wxStatusBar(parent, id, style, name), curPos(0)
{
    this->parent = parent;
    Connect(wxEVT_SIZE, wxSizeEventHandler(EnhancedStatusBar::OnSize));
    DoSize();
}
EnhancedStatusBar::~EnhancedStatusBar()
{
    for (vector<EnhancedStatusBarItem*>::iterator i = items.begin(); i != items.end(); i++)
        delete *i;
    Disconnect(wxEVT_SIZE, wxSizeEventHandler(EnhancedStatusBar::OnSize));
}
void EnhancedStatusBar::OnSize(wxSizeEvent &event)
{
    DoSize();

    event.Skip();
}

bool EnhancedStatusBar::AddWidget(wxWindow *widget, ESB_HorizontalAlignment horizontalAlignment, ESB_VerticalAlignment verticalAlignment, int pos)
{
    if (pos == -1)
    {
        pos = curPos;
        curPos++;
    }

    if (GetFieldsCount() <= pos)
        return false;
    bool found = false;
    unsigned int index;
    for (unsigned int i = 0; i < items.size(); i++)
    {
        EnhancedStatusBarItem *item = items[i];
        if (item->pos == pos)
        {
            RemoveChild(item->widget);
            item->widget->Destroy();
            delete item;
            found = true;
            index = i;
            break;
        }
    }
    EnhancedStatusBarItem *item = new EnhancedStatusBarItem(widget, pos, horizontalAlignment, verticalAlignment);
    if (found)
        items[index] = item;
    else
        items.push_back(item);

    DoSize();
    return true;
}

void EnhancedStatusBar::DoSize()
{
    for (vector<EnhancedStatusBarItem*>::iterator i = items.begin(); i != items.end(); i++)
    {
        EnhancedStatusBarItem *item = *i;
        wxWindow *widget = item->widget;
        int pos = item->pos;
        ESB_HorizontalAlignment horizontalAlignment = item->horizontalAlignment;
        ESB_VerticalAlignment verticalAlignment = item->verticalAlignment;
        wxRect rect;

        GetFieldRect(pos, rect);
        wxPoint widgetPos = widget->GetPosition();
        wxSize widgetSize = widget->GetSize();

        if (horizontalAlignment == ESB_EXACT_FIT_HORIZONTAL)
        {
            if (verticalAlignment == ESB_EXACT_FIT_VERTICAL)
            {
                widget->SetSize(rect.GetWidth() - 2, rect.GetHeight() - 2);
                widget->SetPosition(wxPoint(rect.GetX() + 1, rect.GetY() + 1));
            }
            else if (verticalAlignment == ESB_ALIGN_CENTER_VERTICAL)
            {
                if (widgetSize.GetHeight() < rect.GetHeight() - 1)
                {
                    int diffs = (rect.GetHeight() - widgetSize.GetHeight()) / 2;
                    widget->SetSize(rect.GetWidth() - 2, widgetSize.GetHeight());
                    widget->SetPosition(wxPoint(rect.GetX() + 1, rect.GetY() + diffs));
                }
                else
                {
                    widget->SetSize(rect.GetWidth() - 2, widgetSize.GetHeight());
                    widget->SetPosition(wxPoint(rect.GetX() + 1, rect.GetY() + 1));
                }
            }
            else if (verticalAlignment == ESB_ALIGN_TOP)
            {
                widget->SetSize(rect.GetWidth() - 2, widgetSize.GetHeight());
                widget->SetPosition(wxPoint(rect.GetX() + 1, rect.GetY()));
            }
            else if (verticalAlignment == ESB_ALIGN_BOTTOM)
            {
                widget->SetSize(rect.GetWidth() - 2, widgetSize.GetHeight());
                widget->SetPosition(wxPoint(rect.GetX() + 1, rect.GetHeight() - widgetSize.GetHeight()));
            }
        }
        else if (horizontalAlignment == ESB_ALIGN_LEFT)
        {
            int xPos = rect.GetX() + 1;
            if (verticalAlignment == ESB_EXACT_FIT_VERTICAL)
            {
                widget->SetSize(widgetSize.GetWidth(), rect.GetHeight() - 2);
                widget->SetPosition(wxPoint(xPos, rect.GetY() + 1));
            }
            else if (verticalAlignment == ESB_ALIGN_CENTER_VERTICAL)
            {
                if (widgetSize.GetHeight() < rect.GetHeight() - 1)
                {
                    int diffs = (rect.GetHeight() - widgetSize.GetHeight()) / 2;
                    widget->SetPosition(wxPoint(xPos, rect.GetY() + diffs));
                }
                else
                {
                    widget->SetSize(widgetSize.GetWidth(), rect.GetHeight() - 2);
                    widget->SetPosition(wxPoint(xPos, rect.GetY() - 1));
                }

            }
            else if (verticalAlignment == ESB_ALIGN_TOP)
            {
                widget->SetPosition(wxPoint(xPos, rect.GetY()));
            }
            else if (verticalAlignment == ESB_ALIGN_BOTTOM)
            {
                widget->SetPosition(wxPoint(xPos, rect.GetHeight() - widgetSize.GetHeight()));
            }
        }
        else if (horizontalAlignment == ESB_ALIGN_RIGHT)
        {
            int xPos = rect.GetX() + rect.GetWidth() - widgetSize.GetWidth() + 1;
            if (verticalAlignment == ESB_EXACT_FIT_VERTICAL)
            {
                widget->SetSize(widgetSize.GetWidth(), rect.GetHeight() - 2);
                widget->SetPosition(wxPoint(xPos, rect.GetY() + 1));
            }
            else if (verticalAlignment == ESB_ALIGN_CENTER_VERTICAL)
            {
                if (widgetSize.GetHeight() < rect.GetHeight() - 1)
                {
                    int diffs = (rect.GetHeight() - widgetSize.GetHeight()) / 2;
                    widget->SetPosition(wxPoint(xPos, rect.GetY() + diffs));
                }
                else
                {
                    widget->SetSize(widgetSize.GetWidth(), rect.GetHeight() - 2);
                    widget->SetPosition(wxPoint(xPos, rect.GetY() + 1));
                }
            }
            else if (verticalAlignment == ESB_ALIGN_TOP)
            {
                widget->SetPosition(wxPoint(xPos, rect.GetY()));
            }
            else if (verticalAlignment == ESB_ALIGN_BOTTOM)
            {
                widget->SetPosition(wxPoint(xPos, rect.GetHeight() - widgetSize.GetHeight()));
            }
        }
        else if (horizontalAlignment == ESB_ALIGN_CENTER_HORIZONTAL)
        {
            int xPos = rect.GetX() + (rect.GetWidth() - widgetSize.GetWidth()) / 2 + 1;
            if (verticalAlignment == ESB_EXACT_FIT_VERTICAL)
            {
                widget->SetSize(widgetSize.GetWidth(), rect.GetHeight());
                widget->SetPosition(wxPoint(xPos, rect.GetY()));
            }
            else if (verticalAlignment == ESB_ALIGN_CENTER_VERTICAL)
            {
                if (widgetSize.GetHeight() < rect.GetHeight() - 1)
                {
                    int diffs = (rect.GetHeight() - widgetSize.GetHeight()) / 2;
                    widget->SetPosition(wxPoint(xPos, rect.GetY() + diffs));
                }
                else
                {
                    widget->SetSize(widgetSize.GetWidth(), rect.GetHeight() - 1);
                    widget->SetPosition(wxPoint(xPos, rect.GetY() + 1));
                }
            }
            else if (verticalAlignment == ESB_ALIGN_TOP)
            {
                widget->SetPosition(wxPoint(xPos, rect.GetY()));
            }
            else if (verticalAlignment == ESB_ALIGN_BOTTOM)
            {
                widget->SetPosition(wxPoint(xPos, rect.GetHeight() - widgetSize.GetHeight()));
            }
        }
    }

}